package wiki.kaizen.cloud.security.session.config;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.iherus.shiro.cache.redis.RedisCache;
import org.iherus.shiro.cache.redis.RedisCacheConfigFactory;
import org.iherus.shiro.cache.redis.RedisCachePool;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPoolConfig;
import wiki.kaizen.cloud.security.session.SecurityGlobalConst;
import wiki.kaizen.cloud.security.session.properties.SecurityProperties;

import java.io.Serializable;
import java.util.Deque;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * redis配置
 * @author xeepoo
 * */
@Configuration
public class RedisConfig {

    private final  SecurityProperties.Redis redis;

    public RedisConfig(SecurityProperties securityProperties) {
        this.redis = securityProperties.getRedis();
    }

    /**
     * 配置缓存连接池
     * */
    @Bean
    public JedisPoolConfig poolConfig(){

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMinIdle(redis.getMinIdle());
        config.setMaxIdle(redis.getMaxIdle());
        config.setMaxWaitMillis(redis.getMaxWaitMillis());
        config.setMaxTotal(redis.getMaxTotal());
        return  config;

    }
    /**
     * redis 缓存连接池
     * */
    @Bean
    public RedisCachePool redisCachePool(RedisCacheConfigFactory factory){
        return new RedisCachePool(factory);
    }
    /**
     * 配置缓存工厂
     * */
    @Bean
    public RedisCacheConfigFactory redisCacheConfigFactory(JedisPoolConfig poolConfig){

        RedisCacheConfigFactory factory = new RedisCacheConfigFactory();
        factory.setHost(redis.getHost());
        factory.setPort(redis.getPort());
        factory.setPassword(redis.getPassword());
        factory.setTimeout(redis.getTimeout());
        factory.setPoolConfig(poolConfig);
        factory.setDatabase(redis.getDatabase());
        return factory;
    }

    /**
     * 缓存认证信息 AuthenticationInfo的redis缓存器
     * */
    @SuppressWarnings("unchecked")
    @Bean
    //@ConditionalOnProperty(prefix = "kaizen",name="enableCacheAuth",havingValue = "true")
    public RedisCache<Object, AuthenticationInfo> authenticCache(RedisCachePool redisCachePool){
        RedisCache<Object, AuthenticationInfo> authenticCache = redisCachePool.getCache(SecurityGlobalConst.AUTHENTIC_PREFIX);
        authenticCache.setShiroCacheKeyPrefix(authenticCache.getName());
        return authenticCache;
    }

    /**
     * 缓存健全信息的 AuthorizationInfo redis 缓存器
     * */
    @SuppressWarnings("unchecked")
    @Bean
    //@ConditionalOnProperty(prefix = "kaizen",name="enableCacheAuth",havingValue = "true")
    public RedisCache<Object, AuthorizationInfo> authorizeCache(RedisCachePool redisCachePool){
        RedisCache<Object, AuthorizationInfo> authorize = redisCachePool.getCache(SecurityGlobalConst.AUTHORIZE_PREFIX);
        authorize.setShiroCacheKeyPrefix(authorize.getName());
        return authorize;
    }

    /**
     * 输错密码次数错误的缓存
     * */
    @SuppressWarnings("unchecked")
    @Bean
    public RedisCache<String, AtomicInteger> authfaileCache(RedisCachePool redisCachePool){
        RedisCache<String, AtomicInteger> authfaile = redisCachePool.getCache(SecurityGlobalConst.AUTHFAILE_PREFIX);
        authfaile.setShiroCacheKeyPrefix(authfaile.getName());
        return authfaile;
    }

    /**
     *
     * */
    @SuppressWarnings("unchecked")
    @Bean
    public RedisCache<String, Deque<Serializable>> kickout(RedisCachePool redisCachePool){
        RedisCache<String, Deque<Serializable>> kickout = redisCachePool.getCache(SecurityGlobalConst.KICKOUT_PREFIX);
        kickout.setShiroCacheKeyPrefix(kickout.getName());
        return kickout;
    }
}
